﻿﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
﻿using System.Globalization;
﻿using System.Linq;
﻿using System.Security.Cryptography.X509Certificates;
﻿using System.Windows;
﻿using Arena_Server.Infrastructure;
using Common_Library.Infrastructure;
using Common_Library.Parts_of_map;

namespace GamePlay_Preview.PlayersTools
{
    public class PlayerMove
    {
        private List<Segment> wallList = new List<Segment>();
        private List<ScannedFloor> floorList = new List<ScannedFloor>();
        public PossibleAction lastAction;
        public Dictionary<int, double> SmallItemSegmentColorList = new Dictionary<int, double>();
        public Dictionary<int, double> BigItemSegmentColorList = new Dictionary<int, double>();
        private List<Position> previousPositions = new List<Position>();
        private Segment goalSegment = null;
        ScannedFloor oldestScanned = null;
        private int squareMax = 3;
        BigItem goalBigItem = new BigItem(-1, -1);
        SmallItem goalSmallItem = new SmallItem(-1, -1);

        public void FindBestMove(PlayerState state, ClientsGamePreview game)
        {
            PlayerState temp;
            Console.WriteLine("Find best move");
            //zobacz, czy jest mozliwy ruch, ktory zostal do tej pory oceniony najlepiej
            //jesli nie, to wybierz kolejne
            //jesli zadnego nie mozna wybrac, to pierwszy
            foreach (var action in game.SortedIndexes)
            {
                temp = game.MoveHistory[action.Key];
                if (game.PossibleMoveList.Any(m => temp.MoveDirection == m.MoveDirection && temp.MoveType == m.Action &&
                                                   PlayerState.IsStatesEqual(temp, Translator.GetTempState(game, m)) &&
                                                   (m.Action != MoveType.Shoot || (m.Action == MoveType.Shoot && 
                                                   temp.ConsequenceOfMove == getPossibleConsequenceForShoot(game, temp)))))
                {
                    state.MoveType = temp.MoveType;
                    state.MoveDirection = temp.MoveDirection;
                    return;
                }
            }
            state.MoveDirection = game.PossibleMoveList[0].MoveDirection;
            state.MoveType = game.PossibleMoveList[0].Action;
        }

        /// <summary>
        /// Dla akcji shoot (w danym kierunku) metoda sprawdza jaka bedzie konsekwencja
        /// </summary>
        /// <param name="game"></param>
        /// <param name="playerState">obiekt PlayerState ktory okresla czy akcja ktora bierzemy pod uwage jest shootem i jesli tak
        /// to w jakim kierunku</param>
        /// <returns></returns>
        private MoveConsequence getPossibleConsequenceForShoot(ClientsGamePreview game, PlayerState playerState)
        {
            Position myLocalPosition = Translator.GetMyLocalPosition(game.MyPosition);
            if (playerState.MoveType == MoveType.Shoot)
            {
                if (playerState.MoveDirection == Directions.Left)
                    for (int i = 1; i <= 4; i++)
                    {
                        if (game.CurrentMap.GlobalMap[myLocalPosition.Y, myLocalPosition.X - i] is Wall)
                            return MoveConsequence.ShotAndHitWall;
                        else if (game.CurrentMap.GlobalMap[myLocalPosition.Y, myLocalPosition.X - i].Robot != null)
                            return MoveConsequence.ShotAndHitPlayer;
                        if (i == 4)
                            return MoveConsequence.ShootAndNothingHappen;
                    }
                else if (playerState.MoveDirection == Directions.Right)
                    for (int i = 1; i <= 4; i++)
                    {
                        if (game.CurrentMap.GlobalMap[myLocalPosition.Y, myLocalPosition.X + i] is Wall)
                            return MoveConsequence.ShotAndHitWall;
                        else if (game.CurrentMap.GlobalMap[myLocalPosition.Y, myLocalPosition.X + i].Robot != null)
                            return MoveConsequence.ShotAndHitPlayer;
                        if (i == 4)
                            return MoveConsequence.ShootAndNothingHappen;
                    }
                else if (playerState.MoveDirection == Directions.Up)
                    for (int i = 1; i <= 4; i++)
                    {
                        if (game.CurrentMap.GlobalMap[myLocalPosition.Y - i, myLocalPosition.X] is Wall)
                            return MoveConsequence.ShotAndHitWall;
                        else if (game.CurrentMap.GlobalMap[myLocalPosition.Y - i, myLocalPosition.X].Robot != null)
                            return MoveConsequence.ShotAndHitPlayer;
                        if (i == 4)
                            return MoveConsequence.ShootAndNothingHappen;
                    }
                else if (playerState.MoveDirection == Directions.Down)
                    for (int i = 1; i <= 4; i++)
                    {
                        if (game.CurrentMap.GlobalMap[myLocalPosition.Y + i, myLocalPosition.X] is Wall)
                            return MoveConsequence.ShotAndHitWall;
                        else if (game.CurrentMap.GlobalMap[myLocalPosition.Y + i, myLocalPosition.X].Robot != null)
                            return MoveConsequence.ShotAndHitPlayer;
                        if (i == 4)
                            return MoveConsequence.ShootAndNothingHappen;
                    }
            }
            return MoveConsequence.NULL;
        }


        /// <summary>
        /// Finds a testing move for the game up to some specified number of rounds
        /// </summary>
        /// <param name="state"></param>
        /// <param name="game"></param>
        public void FindTestingMove(PlayerState state, ClientsGamePreview game)
        {
            makeWallAndFloorList(game);
            markFloorAsSeen(game);
            //ConsoleWriter.DisplaySegmentList(wallList);

            SortPossibleActionsMoveLast(game.PossibleMoveList);
            //ConsoleWriter.DisplayPossibleMoves(game.PossibleMoveList);

            var wasPositiveScore = false;
            bool moveWithZeroPoints = false;
            var negativeMoves = new List<PossibleAction>();
            //ustawianie akcji do wykonania na podstawie historii
            if (game.MoveHistory != null && game.MoveHistory.Any())
            {
                foreach (var action in game.PossibleMoveList)
                {
                    // elementy w historii, zawierajace takie same akcje jak action
                    List<PlayerState> items = game.MoveHistory.Where(m => m.MoveType == action.Action).ToList();
                    if (items != null && items.Any())
                    {
                        var ps = new PlayerState();
                        Translator.AddState(ref ps, game.lastConsequence, game.MyPosition, game.CurrentMap, action);
                        ps.MoveDirection = action.MoveDirection;
                        ps.MoveType = action.Action;

                        var any = false;
                        for (int i = 0; i < items.Count; i++)
                        {
                            //sprawdzenie, czy nie byl juz wykonany ten ruch w konkretnym kierunku i stanie
                            if (items[i].MoveDirection == action.MoveDirection &&
                                PlayerState.IsStatesEqual(items[i], ps) && 
                                (action.Action != MoveType.Shoot || (action.Action == MoveType.Shoot &&
                                items[i].ConsequenceOfMove == getPossibleConsequenceForShoot(game, ps))))
                            {
                                any = true;
                                //sprawdzenie, czy ta akcja dala nam kiedys score wiekszy od 0
                                if (items[i].PlayerScore > 0)
                                {
                                    wasPositiveScore = true;
                                    //break;
                                }
                                else if (items[i].PlayerScore == 0)
                                    moveWithZeroPoints = true;
                                else
                                    negativeMoves.Add(action);
                            }


                        }

                        if (!any)
                        {
                            //zapisywanie znalezionego ruchu jako tego, ktory testowo wykonamy
                            state.MoveDirection = action.MoveDirection;
                            state.MoveType = action.Action;
                            return;
                        }
                    }
                    else
                    {
                        state.MoveDirection = action.MoveDirection;
                        state.MoveType = action.Action;
                        return;
                    }
                }

                //jesli jest mozliwa jakas akcja, ktora dala nam kiedys dodatnie punkty, to wykonaj taką
                if (wasPositiveScore)
                {
                    FindBestMove(state, game);
                    return;
                }
                // jesli byly same ujemne punkty, to wykonuj takie ruchy, zeby jak najmniej stracic
                else if (!moveWithZeroPoints)
                {
                    FindBestMove(state, game);
                    return;

                }
                else if (moveWithZeroPoints)
                {
                    var size = negativeMoves.Count;
                    for (int i = 0; i < size; i++)
                        game.PossibleMoveList.Remove(negativeMoves[i]);
                }
                if (pickItems(game, state))
                    return;

            }
            else  //wykonywane jesli historia jest pusta (pierwszy krok)
            {
                state.MoveDirection = game.PossibleMoveList[0].MoveDirection;
                state.MoveType = game.PossibleMoveList[0].Action;
                return;
            }
            Console.WriteLine(@"Eksploracja");
            if (exploreBoard(game, state))
                return;
            Console.WriteLine(@"Cos nie wyszlo");
            FindBestMove(state, game);
        }


        #region STRZELANIE z rożróżnieniem na konsekwencje ruchu

        private bool shoot(ClientsGamePreview game, PlayerState state)
        {
            if (shootPlayer(game, state))
                return true;
            else if (shootWall(game, state))
                return true;
            else if (shootNothing(game, state))
                return true;

            return false;
        }

        /// <summary>
        /// Strzel w nicość
        /// </summary>
        /// <param name="game"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private bool shootNothing(ClientsGamePreview game, PlayerState state)
        {
            Position position = game.MyPosition;

            for (int i = 1; i <= 4; i++)
            {
                //góra
                if ((FindClosestWallToShoot(new Position(position.X, position.Y - i)) == null && PlayersToShoot(game).Count == 0) && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Up))
                {
                    Console.WriteLine(@"Strzał w górę o: " + i);
                    state.MoveDirection = Directions.Up;
                    state.MoveType = MoveType.Shoot;
                    state.ConsequenceOfMove = MoveConsequence.ShootAndNothingHappen;
                    return true;

                }
                //dół
                if ((FindClosestWallToShoot(new Position(position.X, position.Y + i)) == null && PlayersToShoot(game).Count == 0) && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Down))
                {
                    Console.WriteLine(@"Strzał w dół o: " + i);
                    state.MoveDirection = Directions.Down;
                    state.MoveType = MoveType.Shoot;
                    state.ConsequenceOfMove = MoveConsequence.ShootAndNothingHappen;
                    return true;

                }
                //prawo
                if ((FindClosestWallToShoot(new Position(position.X - i, position.Y)) == null && PlayersToShoot(game).Count == 0) && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Right))
                {
                    Console.WriteLine(@"Strzał w prawo  o: " + i);
                    state.MoveDirection = Directions.Right;
                    state.MoveType = MoveType.Shoot;
                    state.ConsequenceOfMove = MoveConsequence.ShootAndNothingHappen;
                    return true;

                }
                //lewo
                if ((FindClosestWallToShoot(new Position(position.X + i, position.Y)) == null && PlayersToShoot(game).Count == 0) && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Up))
                {
                    Console.WriteLine(@"Strzał w lewo o: " + i);
                    state.MoveDirection = Directions.Left;
                    state.MoveType = MoveType.Shoot;
                    state.ConsequenceOfMove = MoveConsequence.ShootAndNothingHappen;
                    return true;

                }
            }



            return false;

        }

        #region STRZAŁ W ŚCIANĘ
        /// <summary>
        /// Strzel w ścianę
        /// </summary>
        /// <param name="game"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        private bool shootWall(ClientsGamePreview game, PlayerState state)
        {
            Position position = game.MyPosition;
            var wall = FindClosestWallToShoot(position); // ściana do ustrzelenia  
            if (wall == null) return false;

            Position localPosition = Translator.GetMyLocalPosition(position);


            if (wall.X == position.X)
            {
                for (int i = 1; i <= 4; i++)
                {

                    if (wall.Y == (position.Y - i) && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Up))
                    {

                        if (i > 1 && game.CurrentMap.GlobalMap[localPosition.Y - i + 1, localPosition.X].Robot == null)
                        {

                            Console.WriteLine(@"Strzał do ściany w górę oddalonej od robota o: " + i);
                            state.MoveDirection = Directions.Up;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitWall;


                            return true;
                        }

                    }
                    if (wall.Y == position.Y + i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Down))
                    {

                        if (i > 1 && game.CurrentMap.GlobalMap[localPosition.Y + i + -1, localPosition.X].Robot == null)
                        {
                            Console.WriteLine(@"Strzał do ściany w dół oddalonej od robota o: " + i);
                            state.MoveDirection = Directions.Down;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitWall;
                            return true;
                        }

                    }
                }
            }
            if (wall.Y == position.Y)
            {
                for (int i = 1; i <= 4; i++)
                {

                    if (wall.X == position.X - i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Left))
                    {

                        if (i > 1 && game.CurrentMap.GlobalMap[localPosition.Y, localPosition.X - i + 1].Robot == null)
                        {
                            Console.WriteLine(@"Strzał do ściany w lewo oddalonej od robota o: " + i);
                            state.MoveDirection = Directions.Left;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitWall;
                            return true;
                        }

                    }
                    if (wall.X == position.X + i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Right))
                    {

                        if (i > 1 && game.CurrentMap.GlobalMap[localPosition.Y, localPosition.X + i - 1].Robot == null)
                        {
                            Console.WriteLine(@"Strzał do ściany w prawo oddalonej od robota o: " + i);
                            state.MoveDirection = Directions.Right;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitWall;
                            return true;
                        }

                    }
                }
            }


            return false;

        }

        private Segment FindClosestWallToShoot(Position position)
        {
            Segment wall = new Segment();
            List<Segment> walls = wallsToShoot(position);


            if (walls.Any())
            {
                wall = walls[0];
                if (wall != null)
                {
                    int pathLength;
                    int closestPath = Math.Abs(wall.X - position.X) + Math.Abs(wall.Y - position.Y);
                    foreach (Segment w in walls)
                    {
                        pathLength = Math.Abs(w.X - position.X) + Math.Abs(w.Y - position.Y);
                        if (pathLength < closestPath)
                        {
                            wall = w;
                            closestPath = pathLength;
                        }
                    }
                }
            }
            return wall;
        }

        private List<Segment> wallsToShoot(Position position)
        {
            List<Segment> walls = new List<Segment>();


            for (int i = 1; i <= 4; i++)
            {
                // góra
                if (wallList.Exists(w => w.X == position.X && w.Y == position.Y - i))
                {
                    var wall = wallList.Find(w => w.X == position.X && w.Y == position.Y - i);
                    if (wall != null && !walls.Contains(wall))
                        walls.Add(wall);
                }
                // dół
                if (wallList.Exists(w => w.X == position.X && w.Y == position.Y + i))
                {
                    var wall = wallList.Find(w => w.X == position.X && w.Y == position.Y + i);
                    if (wall != null && !walls.Contains(wall))
                        walls.Add(wall);
                }
                // lewo
                if (wallList.Exists(w => w.X == position.X - i && w.Y == position.Y))
                {
                    var wall = wallList.Find(w => w.X == position.X - i && w.Y == position.Y);
                    if (wall != null && !walls.Contains(wall))
                        walls.Add(wall);
                }
                // prawo
                if (wallList.Exists(w => w.X == position.X + i && w.Y == position.Y))
                {
                    var wall = wallList.Find(w => w.X == position.X + i && w.Y == position.Y);
                    if (wall != null && !walls.Contains(wall))
                        walls.Add(wall);
                }

            }

            return walls;
        }
        #endregion
        #region STRZAŁ DO FAGASÓW

        /// <summary>
        /// Strzel w przeciwnika
        /// </summary>
        /// <param name="game"></param>
        /// <param name="state"></param>
        private bool shootPlayer(ClientsGamePreview game, PlayerState state)
        {
            Position position = game.MyPosition;
            var floors = PlayersToShoot(game);
            if (floors.Count == 0) return false;

            var floor = floors[0] ?? FindClosestRobot(floors, position);
            if (floor == null) return false;

            if (floor.FloorSegment.X == position.X)
            {
                for (int i = 1; i <= 4; i++)
                {
                    if (floor.FloorSegment.Y == position.Y - i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Up))
                    {

                        if (i > 1 && !wallList.Exists(w => w.X == game.MyPosition.X && w.Y == game.MyPosition.Y - i + 1))
                        {
                            Console.WriteLine(@"ooooooo nie ma ściany miedzy nami");
                            Console.WriteLine(@"Strzał do robota w górę oddalonego od layz o: " + i);
                            state.MoveDirection = Directions.Up;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitPlayer;
                            return true;
                        }

                    }
                    if (floor.FloorSegment.Y == position.Y + i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Down))
                    {
                        // przeszkoda w postaci ściany na drodze 
                        if (i > 1 && !wallList.Exists(w => w.X == game.MyPosition.X && w.Y == game.MyPosition.Y + i - 1))
                        {
                            Console.WriteLine(@"ooooooo nie ma ściany miedzy nami");
                            Console.WriteLine(@"Strzał do robota w górę oddalonego od layz o: " + i);
                            state.MoveDirection = Directions.Down;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitPlayer;
                            return true;
                        }


                    }
                }
            }
            if (floor.FloorSegment.Y == position.Y)
            {
                for (int i = 1; i <= 4; i++)
                {
                    if (floor.FloorSegment.X == position.X - i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Left))
                    {
                        // przeszkoda w postaci ściany na drodze 
                        if (i > 1 && wallList.Exists(w => w.X == game.MyPosition.X - i + 1 && w.Y == game.MyPosition.Y))
                        {
                            Console.WriteLine(@"ooooooo nie ma ściany miedzy nami");
                            Console.WriteLine(@"Strzał do robota w górę oddalonego od layz o: " + i);
                            state.MoveDirection = Directions.Left;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitPlayer;
                            return true;
                        }

                    }
                    if (floor.FloorSegment.X == position.X + i && game.PossibleMoveList.Any(m => m.Action == MoveType.Shoot && m.MoveDirection == Directions.Right))
                    {
                        // przeszkoda w postaci ściany na drodze 
                        if (i > 1 && wallList.Exists(w => w.X == game.MyPosition.X + i - 1 && w.Y == game.MyPosition.Y))
                        {
                            Console.WriteLine(@"ooooooo nie ma ściany miedzy nami");
                            Console.WriteLine(@"Strzał do robota w górę oddalonego od layz o: " + i);
                            state.MoveDirection = Directions.Right;
                            state.MoveType = MoveType.Shoot;
                            state.ConsequenceOfMove = MoveConsequence.ShotAndHitPlayer;
                            return true;
                        }

                    }
                }
            }

            return false;

        }

        private ScannedFloor FindClosestRobot(List<ScannedFloor> floors, Position position)
        {
            ScannedFloor closetScannedFloor = floors[0];
            if (closetScannedFloor != null)
            {
                int pathLength;
                int closestPath = Math.Abs(closetScannedFloor.FloorSegment.X - position.X) +
                                   Math.Abs(closetScannedFloor.FloorSegment.Y - position.Y);

                foreach (ScannedFloor sf in floors)
                {
                    pathLength = Math.Abs(sf.FloorSegment.X - position.X) + Math.Abs(sf.FloorSegment.Y - position.Y);
                    if (pathLength < closestPath)
                    {
                        closetScannedFloor = sf;
                        closestPath = pathLength;
                    }
                }
            }

            return closetScannedFloor;
        }
        /// <summary>
        /// Znajduje podłogi z przeciwnikami
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        private List<ScannedFloor> PlayersToShoot(ClientsGamePreview game)
        {

            List<ScannedFloor> floors = new List<ScannedFloor>();
            Position localPosition = Translator.GetMyLocalPosition(game.MyPosition);
            for (int i = 1; i <= 4; i++)
            {
                // góra
                if (floorList.Exists(fl => fl.FloorSegment.X == game.MyPosition.X && fl.FloorSegment.Y == game.MyPosition.Y - i))
                {
                    var floor = floorList.Find(f => f.FloorSegment.X == game.MyPosition.X && f.FloorSegment.Y == game.MyPosition.Y - i);


                    if (floor != null && !floors.Contains(floor) && game.CurrentMap.GlobalMap[localPosition.Y - i, localPosition.X].Robot != null)
                        floors.Add(floor);

                }
                //dół
                if (floorList.Exists(fl => fl.FloorSegment.X == game.MyPosition.X && fl.FloorSegment.Y == game.MyPosition.Y + i))
                {
                    var floor = floorList.Find(f => f.FloorSegment.X == game.MyPosition.X && f.FloorSegment.Y == game.MyPosition.Y + i);


                    if (floor != null && !floors.Contains(floor) && game.CurrentMap.GlobalMap[localPosition.Y + i, localPosition.X].Robot != null)
                        floors.Add(floor);

                }

                // lewo
                if (floorList.Exists(fl => fl.FloorSegment.X == game.MyPosition.X - i && fl.FloorSegment.Y == game.MyPosition.Y))
                {


                    var floor = floorList.Find(f => f.FloorSegment.X == game.MyPosition.X - i && f.FloorSegment.Y == game.MyPosition.Y);


                    if (floor != null && !floors.Contains(floor) && game.CurrentMap.GlobalMap[localPosition.Y, localPosition.X - i].Robot != null)
                        floors.Add(floor);

                }
                //prawo
                if (floorList.Exists(fl => fl.FloorSegment.X == game.MyPosition.X + i && fl.FloorSegment.Y == game.MyPosition.Y))
                {
                    var floor = floorList.Find(f => f.FloorSegment.X == game.MyPosition.X + i && f.FloorSegment.Y == game.MyPosition.Y);
                    if (floor != null && !floors.Contains(floor) && game.CurrentMap.GlobalMap[localPosition.Y, localPosition.X + i].Robot != null)
                        if (i > 1 && !wallList.Exists(w => w.X == game.MyPosition.X + i - 1 && w.Y == game.MyPosition.Y))
                            floors.Add(floor);
                }

            }

            return floors;
        }

        #endregion

        #endregion
        #region ZBIERANIE PRZEDMIOTÓW
        /// <summary>
        /// Metoda do wyszukiwania itemow
        /// </summary>
        /// <param name="game"></param>
        /// <param name="state"></param>
        /// <returns>false jesli nie mozemy zebrac lub dazyc do zebrania itemu (np jesli wszystkie sa odgrodzone scianami)</returns>
        private bool pickItems(ClientsGamePreview game, PlayerState state)
        {
            List<SmallItem> smallItems = new List<SmallItem>(game.CurrentMap.SmallItemList);
            List<BigItem> bigItems = new List<BigItem>(game.CurrentMap.BigItemList);
            Position position = game.MyPosition;
            Position localPosition = Translator.GetMyLocalPosition(position);

            //jesli podnoszenie daje punkty, to opusc
            if (game.MyBigItem &&
                BigItemSegmentColorList.Any(s => s.Value > 0 && s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == position.X && f.FloorSegment.Y == position.Y).FloorSegment.Color)))
            {
                state.MoveType = MoveType.DropBigItem;
                state.MoveDirection = Directions.NULL;
                return true;
            }
            //jesli opuszczanie daje punkty, to podnies
            else if (!game.MyBigItem && game.CurrentMap.GlobalMap[localPosition.Y, localPosition.X].HasBigItem &&
                BigItemSegmentColorList.Any(s => s.Value > 0 && s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == position.X && f.FloorSegment.Y == position.Y).FloorSegment.Color)))
            {
                state.MoveType = MoveType.PickBigItem;
                state.MoveDirection = Directions.NULL;
                return true;
            }
            if (game.MyBigItem)
            {
                state.MoveType = MoveType.DropBigItem;
                state.MoveDirection = Directions.NULL;
                return true;
            }


            //czy jest na liscie taki item, ktory lezy na takim kolorze podlogi, z ktorego itemu nie zbieralysmy  
            var isSmallItemNewColor = smallItems.Any(b => floorList.Any(f => f.FloorSegment.X == b.X && f.FloorSegment.Y == b.Y && SmallItemSegmentColorList.Any(i => i.Key != Translator.GetColor(f.FloorSegment.Color))));
            var isBigItemNewColor = bigItems.Any(b => BigItemSegmentColorList.Any(i => i.Key != Translator.GetColor(b.Color)));

            #region duze przedmioty
            if (((!game.MoveHistory.Any(m => m.MoveType == MoveType.PickBigItem) || isBigItemNewColor) && !game.MyBigItem &&
                     game.CurrentMap.BigItemList != null && game.CurrentMap.BigItemList.Any()) ||
                    (game.CurrentMap.BigItemList != null && game.CurrentMap.BigItemList.Any() && !game.MyBigItem &&
                     game.MoveHistory.Any(m => m.MoveType == MoveType.PickBigItem && m.PlayerScore > 0)))
            {

                Console.WriteLine("Zbieranie duzych przedmiotow");
                BigItem closestBigItem;
                //sprawdzamy najblizszy przedmiot, czy jest miedzy robotem a itemem sciana; jesli tak, to szukamy kolejnego najblizszego
                var count = bigItems.Count;
                for (int i = 0; i < count; i++)
                {
                    if (!bigItems.Any(m => m.X == goalBigItem.X && m.Y == goalBigItem.Y))
                        goalBigItem = null;
                    //Console.WriteLine(goalBigItem == null);
                    closestBigItem = goalBigItem ?? (goalBigItem = FindClosestBigItem(bigItems, position));

                    //jesli przedmiot na kafelku o danym kolorze nie byl zbierany lub byl i dal punkty dodatnie
                    if (!BigItemSegmentColorList.Any(s => s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == goalBigItem.X && f.FloorSegment.Y == goalBigItem.Y).FloorSegment.Color)) ||
                        BigItemSegmentColorList.Any(s => s.Value > 0 && s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == goalBigItem.X && f.FloorSegment.Y == goalBigItem.Y).FloorSegment.Color)))
                    {
                        //Console.WriteLine(goalBigItem.X + " " + closestBigItem.X + " " + goalBigItem.Y + " " + closestBigItem.Y);
                        int Y = position.Y - closestBigItem.Y;
                        int X = position.X - closestBigItem.X;
                        //jesli nie ma sciany miedzy robotem a itemem
                        if (!wallList.Any(w => Math.Abs(position.Y - w.Y) <= Math.Abs(Y) &&
                                               (Math.Sign(position.Y - w.Y) == Math.Sign(Y)) &&
                                               Math.Abs(position.X - w.X) <= Math.Abs(X) &&
                                               (Math.Sign(position.X - w.X) == Math.Sign(X))))
                        {
                            if (moveTowardsItem(X, Y, state, game, new PossibleAction(MoveType.PickBigItem)))
                                return true;
                        }
                        else
                        {
                            var item = bigItems.First(b => b.X == closestBigItem.X && b.Y == closestBigItem.Y);
                            bigItems.Remove(item);
                        }
                    }
                    else
                    {
                        var item = bigItems.First(b => b.X == closestBigItem.X && b.Y == closestBigItem.Y);
                        bigItems.Remove(item);
                        goalBigItem = new BigItem(-1, -1);
                    }
                }
            }
            #endregion

            #region małe przedmioty
            if (((!game.MoveHistory.Any(m => m.MoveType == MoveType.PickSmallItem) || isSmallItemNewColor) &&
                 game.CurrentMap.SmallItemList != null && game.CurrentMap.SmallItemList.Any()) ||
                (game.CurrentMap.SmallItemList != null && game.CurrentMap.SmallItemList.Any() &&
                 game.MoveHistory.Any(m => m.MoveType == MoveType.PickSmallItem && m.PlayerScore > 0)))
            {
                Console.WriteLine("Zbieranie malych przedmiotow");
                SmallItem closestSmallItem;
                var count = smallItems.Count;
                for (int i = 0; i < count; i++)
                {
                    //jesli smallItems zawiera goalSmallItem 
                    if (!smallItems.Any(m => m.X == goalSmallItem.X && m.Y == goalSmallItem.Y))
                        goalSmallItem = null;
                    closestSmallItem = goalSmallItem ?? (goalSmallItem = FindClosestSmallItem(smallItems, position));

                    //jesli przedmiot na kafelku o danym kolorze nie byl zbierany lub byl i dal punkty dodatnie
                    if (!SmallItemSegmentColorList.Any(s => s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == goalSmallItem.X && f.FloorSegment.Y == goalSmallItem.Y).FloorSegment.Color)) ||
                        SmallItemSegmentColorList.Any(s => s.Value > 0 && s.Key == Translator.GetColor(floorList.First(f => f.FloorSegment.X == goalSmallItem.X && f.FloorSegment.Y == goalSmallItem.Y).FloorSegment.Color)))
                    {
                        int Y = position.Y - closestSmallItem.Y;
                        int X = position.X - closestSmallItem.X;
                        //jesli nie ma sciany miedzy robotem a itemem
                        if (!wallList.Any(w => Math.Abs(position.Y - w.Y) <= Math.Abs(Y) &&
                                               (Math.Sign(position.Y - w.Y) == Math.Sign(Y)) &&
                                               Math.Abs(position.X - w.X) <= Math.Abs(X) &&
                                               (Math.Sign(position.X - w.X) == Math.Sign(X))))
                        {
                            if (moveTowardsItem(X, Y, state, game, new PossibleAction(MoveType.PickSmallItem)))
                                return true;
                        }
                        else
                            smallItems.Remove(closestSmallItem);
                    }
                    else
                    {
                        goalSmallItem = new SmallItem(-1, -1);
                        smallItems.Remove(closestSmallItem);
                    }
                }
            }
            #endregion

            return false;
        }

        /// <summary>
        /// Poruszanie sie w kierunku danego celu (jesli nie ma sciany pomiedzy!!) na podstawie odleglosci i wykonywanie akcji docelowej
        /// </summary>
        /// <param name="X">roznica miedzy myPosition.X i jakimsCelem.X</param>
        /// <param name="Y">roznica miedzy myPosition.Y i jakimsCelem.Y</param>
        /// <param name="state"></param>
        /// <param name="game"></param>
        /// <param name="goalAction">akcja docelowa</param>
        /// <returns></returns>
        private bool moveTowardsItem(int X, int Y, PlayerState state, ClientsGamePreview game, PossibleAction goalAction)
        {
            if (Y < 0 && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Down))
            {
                state.MoveDirection = Directions.Down;
                state.MoveType = MoveType.MakeMove;
                return true;
            }
            else if (Y > 0 && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Up))
            {
                state.MoveDirection = Directions.Up;
                state.MoveType = MoveType.MakeMove;
                return true;
            }
            else if (X < 0 && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Right))
            {
                state.MoveDirection = Directions.Right;
                state.MoveType = MoveType.MakeMove;
                return true;
            }
            else if (X > 0 && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Left))
            {
                state.MoveDirection = Directions.Left;
                state.MoveType = MoveType.MakeMove;
                return true;
            }
            else if (X == 0 && Y == 0 && goalAction != null)
            {
                state.MoveDirection = goalAction.MoveDirection;
                state.MoveType = goalAction.Action;
                return true;
            }
            return false;
        }


        private SmallItem FindClosestSmallItem(List<SmallItem> smallItems, Position position)
        {

            SmallItem closestSmallItem;
            if (smallItems == null || !smallItems.Any()) return null;
            closestSmallItem = smallItems[0];
            int pathLength;
            int closestPath = Math.Abs(closestSmallItem.X - position.X) +
                              Math.Abs(closestSmallItem.Y - position.Y);

            foreach (SmallItem si in smallItems)
            {
                pathLength = Math.Abs(si.X - position.X) + Math.Abs(si.Y - position.Y);
                if (pathLength < closestPath)
                {
                    closestSmallItem = si;
                    closestPath = pathLength;
                }
            }
            return closestSmallItem;


        }

        private BigItem FindClosestBigItem(List<BigItem> bigItems, Position position)
        {

            BigItem closestBigItem = bigItems[0];
            int pathLength;
            int closestPath = Math.Abs(closestBigItem.X - position.X) +
                               Math.Abs(closestBigItem.Y - position.Y);

            foreach (BigItem bi in bigItems)
            {
                pathLength = Math.Abs(bi.X - position.X) + Math.Abs(bi.Y - position.Y);
                if (pathLength < closestPath)
                {
                    closestBigItem = bi;
                    closestPath = pathLength;
                }
            }
            return closestBigItem;
        }
        #endregion
        private void makeWallAndFloorList(ClientsGamePreview game)
        {
            var myLocalPosition = Translator.GetMyLocalPosition(game.MyPosition);
            int x = 0, y = 0;
            //wykonywane gdy historia jest pusta
            #region ZaPierwszymRazem
            if (previousPositions.Count == 0)
            {
                previousPositions.Add(game.MyPosition.Copy());
                for (int i = 0; i < 17; i++)
                {
                    for (int j = 0; j < 17; j++)
                        if (game.CurrentMap.GlobalMap[j, i] != null)
                        {
                            x = game.MyPosition.X - (myLocalPosition.X - i);
                            y = game.MyPosition.Y - (myLocalPosition.Y - j);

                            if (game.CurrentMap.GlobalMap[j, i] is Wall)
                            {
                                wallList.Add(new Wall() { X = x, Y = y, Color = game.CurrentMap.GlobalMap[j, i].Color });
                                //Console.WriteLine("Dodana ściana: (" + x + ", " + y + ")");
                            }
                            else
                            {
                                floorList.Add(new ScannedFloor(new Floor() { X = x, Y = y, Color = game.CurrentMap.GlobalMap[j, i].Color },
                                    false, 0));
                            }
                        }
                }
            }
            #endregion

            #region PrzyZrobieniuKroku
            else
            {
                //sprawdzenie, czy juz robot byl kiedys na tej pozycji na mapie (globalnie)
                if (!previousPositions.Any(m => m.X == game.MyPosition.X && m.Y == game.MyPosition.Y))
                {
                    previousPositions.Add(game.MyPosition.Copy());
                    if (lastAction.Action == MoveType.MakeMove)
                    {
                        //Console.WriteLine("my localposition " + myLocalPosition.X + " " + myLocalPosition.Y);
                        int localY = (game.GlobalMapSize.Height - 1 - game.MyPosition.Y) < 8 ? myLocalPosition.Y + (game.GlobalMapSize.Height - 1 - game.MyPosition.Y) : myLocalPosition.Y + 8;
                        int localX = (game.GlobalMapSize.Width - 1 - game.MyPosition.X) < 8 ? myLocalPosition.X + (game.GlobalMapSize.Width - 1 - game.MyPosition.X) : myLocalPosition.X + 8;
                        for (int i = 0; i < 17; i++)
                        {
                            var found = false;
                            int tempx = 0, tempy = 0;
                            if (lastAction.MoveDirection == Directions.Up)
                            {
                                x = game.MyPosition.X - (myLocalPosition.X - i);
                                y = game.MyPosition.Y - myLocalPosition.Y;
                                tempy = 0;
                                tempx = i;

                                if (game.CurrentMap.GlobalMap[0, i] is Wall)
                                    found = true;
                            }
                            else if (lastAction.MoveDirection == Directions.Down)
                            {
                                x = game.MyPosition.X - (myLocalPosition.X - i);
                                y = game.MyPosition.Y + (localY - myLocalPosition.Y);
                                tempy = localY;
                                tempx = i;

                                if (game.CurrentMap.GlobalMap[localY, i] is Wall)
                                    found = true;
                            }
                            else if (lastAction.MoveDirection == Directions.Left)
                            {
                                x = game.MyPosition.X - myLocalPosition.X;
                                y = game.MyPosition.Y - (myLocalPosition.Y - i);
                                tempy = i;
                                tempx = 0;

                                if (game.CurrentMap.GlobalMap[i, 0] is Wall)
                                    found = true;
                            }
                            else if (lastAction.MoveDirection == Directions.Right)
                            {
                                x = game.MyPosition.X + (localX - myLocalPosition.X);
                                y = game.MyPosition.Y - (myLocalPosition.Y - i);
                                tempy = i;
                                tempx = localX;

                                if (game.CurrentMap.GlobalMap[i, localX] is Wall)
                                    found = true;
                            }

                            if (found && !wallList.Any(m => m.X == x && m.Y == y))
                            {
                                wallList.Add(new Wall { X = x, Y = y, Color = game.CurrentMap.GlobalMap[tempy, tempx].Color });
                                //Console.WriteLine("Dodana ściana: (" + x + ", " + y + ")");
                            }
                            if (!found && !floorList.Any(m => m.FloorSegment.X == x && m.FloorSegment.Y == y) && game.CurrentMap.GlobalMap[tempy, tempx] != null)
                            {
                                floorList.Add(new ScannedFloor(new Floor { X = x, Y = y, Color = game.CurrentMap.GlobalMap[tempy, tempx].Color },
                                    false, 0));
                            }
                        }
                    }
                }
            }
            #endregion
        }

        /// <summary>
        ///     Sortowanie PossibleActionsList, zeby najpierw wybierac do testowania te, ktore odbywaja sie w tym samym miejscu
        /// </summary>
        /// <param name="actions"></param>
        private void SortPossibleActionsMoveLast(List<PossibleAction> actions)
        {
            int i = 0;
            int j = actions.Count - 1;

            //ustawiamy wszystkie akcje z shoot na poczatku listy
            while (i < j)
            {
                if (actions[i].MoveDirection == Directions.NULL || actions[i].Action == MoveType.Shoot)
                {
                    i++;
                    continue;
                }
                if (actions[j].MoveDirection == Directions.NULL || actions[j].Action == MoveType.Shoot)
                {
                    PossibleAction temp = actions[i];
                    actions[i] = actions[j];
                    actions[j] = temp;
                    i++;
                    j--;
                }
                else
                    j--;
            }
        }


        /// <summary>
        /// Zaznacza, ktore kafelki byly juz zwiedzane (pomoc w eksploracji)
        /// </summary>
        /// <param name="game"></param>
        private void markFloorAsSeen(ClientsGamePreview game)
        {
            var position = game.MyPosition;
            for (int i = 1; i <= squareMax; i++)
                for (int x = -i; x <= i; x++)
                    for (int y = -i; y <= i; y++)
                    {
                        int Y = position.Y + y;
                        int X = position.X + x;
                        ScannedFloor floor = floorList.FirstOrDefault(m => m.FloorSegment.X == X && m.FloorSegment.Y == Y);
                        if (floor != null)
                        {
                            if (!wallList.Any(w => Math.Abs(position.Y - w.Y) <= Math.Abs(position.Y - Y) &&
                                                   (Math.Sign(position.Y - w.Y) == Math.Sign(position.Y - Y)) &&
                                                   Math.Abs(position.X - w.X) <= Math.Abs(position.X - X) &&
                                                   (Math.Sign(position.X - w.X) == Math.Sign(position.X - X))))
                            {
                                floor.IsScanned = true;
                                floor.RoundScanned = game.CurrentRoundNumber;
                            }
                        }
                    }
        }

        private bool isManhattanWallFree(Position myPosition, Segment goalSegment)
        {
            if (!wallList.Any(w => w.X == myPosition.X &&
               Math.Abs(myPosition.Y - w.Y) <= Math.Abs(myPosition.Y - goalSegment.Y) &&
               (Math.Sign(myPosition.Y - w.Y) == Math.Sign(myPosition.Y - goalSegment.Y))))
                if (!wallList.Any(w => w.Y == goalSegment.Y &&
                                       Math.Abs(myPosition.X - w.X) <= Math.Abs(myPosition.X - goalSegment.X) &&
                                       (Math.Sign(myPosition.X - w.X) == Math.Sign(myPosition.X - goalSegment.X))))
                    return true;
            if (!wallList.Any(w => w.Y == myPosition.Y &&
               Math.Abs(myPosition.X - w.X) <= Math.Abs(myPosition.X - goalSegment.X) &&
               (Math.Sign(myPosition.X - w.X) == Math.Sign(myPosition.X - goalSegment.X))))
                if (!wallList.Any(w => w.X == goalSegment.X &&
                                       Math.Abs(myPosition.Y - w.Y) <= Math.Abs(myPosition.Y - goalSegment.Y) &&
                                       (Math.Sign(myPosition.Y - w.Y) == Math.Sign(myPosition.Y - goalSegment.Y))))
                    return true;
            return false;
        }

        private bool isChosenForExploration(int x, int y, ClientsGamePreview game, PlayerState state, bool openSpace)
        {
            var position = game.MyPosition;
            bool isNoWallWithinSight = false; // czy miedzy robotem i celem nie ma sciany
            int Y = position.Y + y;
            int X = position.X + x;
            ScannedFloor floor =
                floorList.FirstOrDefault(m => m.FloorSegment.X == X && m.FloorSegment.Y == Y);
            if (floor != null)
            {
                if (openSpace && !wallList.Any(w => Math.Abs(position.Y - w.Y) <= Math.Abs(position.Y - Y) &&
                                       (Math.Sign(position.Y - w.Y) == Math.Sign(position.Y - Y)) &&
                                       Math.Abs(position.X - w.X) <= Math.Abs(position.X - X) &&
                                       (Math.Sign(position.X - w.X) == Math.Sign(position.X - X))))
                {
                    isNoWallWithinSight = true;
                    if (!floor.IsScanned)
                    {
                        goalSegment = new Segment { X = X, Y = Y };
                        //Console.WriteLine("not scanned floor, move to goal " + goalSegment.X + ", " + goalSegment.Y);
                        moveTowardsItem(position.X - goalSegment.X, position.Y - goalSegment.Y, state,
                                        game, null);
                        return true;
                    }
                }
                //jesli nie ma sciany przez manhattan distance
                if (!openSpace && isManhattanWallFree(position, floor.FloorSegment))
                {
                    if (!floor.IsScanned)
                    {
                        goalSegment = new Segment { X = X, Y = Y };
                        Console.WriteLine("not scanned floor in manhattan, move to goal " + goalSegment.X + ", " +
                                          goalSegment.Y);
                        moveTowardsItem(position.X - goalSegment.X, position.Y - goalSegment.Y, state, game, null);
                        return true;
                    }
                    if (oldestScanned == null || (oldestScanned.RoundScanned > floor.RoundScanned))
                        oldestScanned = floor;
                }
                if (isNoWallWithinSight && openSpace && (oldestScanned == null || (oldestScanned.RoundScanned > floor.RoundScanned)))
                    oldestScanned = floor;
            }
            return false;
        }

        private bool exploreBoard(ClientsGamePreview game, PlayerState state)
        {
            var position = game.MyPosition;
            if (goalSegment != null)
            {
                var localRobotPosition = Translator.GlobalToLocalPosition(position, new Position(goalSegment.X, goalSegment.Y));
                //jesli jestem na celu lub o krok od niego i robot na nim stoi to wybierz inny cel = ustaw goalSegment na null
                if ((goalSegment.X == position.X && goalSegment.Y == position.Y) ||
                    (((position.X == goalSegment.X && (position.Y == goalSegment.Y - 1 || position.Y == goalSegment.Y + 1)) ||
                      (position.Y == goalSegment.Y && (position.X == goalSegment.X - 1 || position.X == goalSegment.X + 1)))
                     && game.CurrentMap.GlobalMap[localRobotPosition.Y, localRobotPosition.X].Robot != null))
                {
                    goalSegment = null;
                }
                //jesli pojawi sie sciana to ustaw na null
                else if (wallList.Any(w => Math.Abs(position.Y - w.Y) <= Math.Abs(position.Y - goalSegment.Y) &&
                                           (Math.Sign(position.Y - w.Y) == Math.Sign(position.Y - goalSegment.Y)) &&
                                           Math.Abs(position.X - w.X) <= Math.Abs(position.X - goalSegment.X) &&
                                           (Math.Sign(position.X - w.X) == Math.Sign(position.X - goalSegment.X))) &&
                         !isManhattanWallFree(position, goalSegment))
                {
                    goalSegment = null;
                }
                else
                {
                    //Console.WriteLine("move to goal " + goalSegment.X + ", " + goalSegment.Y);
                    if (!moveTowardsItem(position.X - goalSegment.X, position.Y - goalSegment.Y, state, game, null))
                        goalSegment = null;
                    else
                        return true;
                }
            }
            //jesli nie ma wyznaczonego celu
            if (goalSegment == null)
            {
                oldestScanned = null;
                for (int i = 8; i > 0; i--)
                {
                    for (int x = -i; x <= i; x = x + 2 * i)
                        for (int y = -i; y <= i; y++)
                        {
                            if (isChosenForExploration(x, y, game, state, true))
                                return true;
                        }
                    for (int y = -i; y <= i; y = y + 2 * i)
                        for (int x = -i; x <= i; x++)
                        {
                            if (isChosenForExploration(x, y, game, state, true))
                                return true;
                        }
                }
                for (int i = 8; i > 0; i--)
                {
                    for (int x = -i; x <= i; x = x + 2 * i)
                        for (int y = -i; y <= i; y++)
                        {
                            if (isChosenForExploration(x, y, game, state, false))
                                return true;
                        }
                    for (int y = -i; y <= i; y = y + 2 * i)
                        for (int x = -i; x <= i; x++)
                        {
                            if (isChosenForExploration(x, y, game, state, false))
                                return true;
                        }
                }
                if (oldestScanned != null)
                {
                    //Console.WriteLine("move to oldest, move to goal " + oldestScanned.FloorSegment.X + ", " + oldestScanned.FloorSegment.Y);
                    goalSegment = new Segment { X = oldestScanned.FloorSegment.X, Y = oldestScanned.FloorSegment.Y };
                    moveTowardsItem(position.X - goalSegment.X, position.Y - goalSegment.Y, state, game, null);
                    return true;
                }
            }
            return false;
        }

        #region ZlaEksploracjaAleMozeSiePrzyda
        //private Directions currentDirection = Directions.NULL;
        //private int currentStepsCount = 0;
        //private int previousDirectionValue = 100;
        //private int previousOppositeDirectionValue = 100;
        //private int previousDirectionPreviousValue = 100;
        //private int previousOppositeDirectionPreviousValue = 100;
        //private Directions previousDirection = Directions.NULL;
        //private int previousStepsCount = 0;
        //private void explore(ClientsGamePreview game, PlayerState state)
        //{
        //    List<Directions> exploreDirections = new List<Directions> { Directions.Left, Directions.Down, Directions.Right, Directions.Up };
        //    Position myPosition = game.MyPosition;
        //    int maximum = 0, value = 0;
        //    Directions chosenDirection = Directions.NULL;
        //    int chosenDirectionValue = 0;
        //    //sprawdz, w ktora strone moge sie poruszac najdluzej (nie ma scian):
        //    //w lewo
        //    IEnumerable<Segment> walls = new List<Segment>();
        //    if (currentDirection != Directions.Right && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Left))
        //    {
        //        if ((walls = wallList.Where(w => w.Y == myPosition.Y && w.X < myPosition.X)).Any())
        //        {
        //            if (((value = walls.Min(w => myPosition.X - w.X)) <= 8 ? value : (value = 8)) > maximum)
        //            {
        //                maximum = value;
        //                chosenDirection = Directions.Left;
        //            }
        //            if (previousDirection == Directions.Right)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = value;
        //            }
        //            else if (previousDirection == Directions.Left)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = value;
        //            }
        //            if (currentDirection == Directions.Left)
        //                chosenDirectionValue = value;

        //        }
        //        else
        //        {
        //            if (previousDirection == Directions.Right)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = 9;
        //            }
        //            else if (previousDirection == Directions.Left)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = 9;
        //            }
        //            if (currentDirection == Directions.Left)
        //                chosenDirectionValue = 9;

        //            maximum = 9;
        //            chosenDirection = Directions.Left;
        //        }
        //    }
        //    else if (currentDirection != Directions.Right)
        //    {
        //        if (previousDirection == Directions.Right)
        //        {
        //            previousDirectionPreviousValue = previousDirectionValue;
        //            previousDirectionValue = 1;
        //        }
        //        else if (previousDirection == Directions.Left)
        //        {
        //            previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //            previousOppositeDirectionValue = 1;
        //        }
        //    }

        //    //w prawo
        //    if (currentDirection != Directions.Left && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Right))
        //    {
        //        if ((walls = wallList.Where(w => w.Y == myPosition.Y && w.X > myPosition.X)).Any())
        //        {
        //            if (((value = walls.Min(w => w.X - myPosition.X)) <= 8 ? value : (value = 8)) > maximum)
        //            {
        //                maximum = value;
        //                chosenDirection = Directions.Right;
        //            }
        //            if (previousDirection == Directions.Left)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = value;
        //            }
        //            else if (previousDirection == Directions.Right)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = value;
        //            }
        //            if (currentDirection == Directions.Right)
        //                chosenDirectionValue = value;

        //        }
        //        else
        //        {
        //            if (previousDirection == Directions.Left)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = 9;
        //            }
        //            else if (previousDirection == Directions.Right)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = 9;
        //            }
        //            if (currentDirection == Directions.Right)
        //                chosenDirectionValue = 9;

        //            maximum = 9;
        //            chosenDirection = Directions.Right;
        //        }
        //    }
        //    else if (currentDirection != Directions.Left)
        //    {
        //        if (previousDirection == Directions.Left)
        //        {
        //            previousDirectionPreviousValue = previousDirectionValue;
        //            previousDirectionValue = 1;
        //        }
        //        else if (previousDirection == Directions.Right)
        //        {
        //            previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //            previousOppositeDirectionValue = 1;
        //        }
        //    }


        //    //w dol
        //    if (currentDirection != Directions.Up && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Down))
        //    {
        //        if ((walls = wallList.Where(w => w.X == myPosition.X && w.Y > myPosition.Y)).Any())
        //        {
        //            if (((value = walls.Min(w => w.Y - myPosition.Y)) <= 8 ? value : (value = 8)) > maximum)
        //            {
        //                maximum = value;
        //                chosenDirection = Directions.Down;
        //            }
        //            else if (value == maximum && currentDirection == Directions.Down)
        //            {
        //                chosenDirection = Directions.Down;
        //            }
        //            if (previousDirection == Directions.Up)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = value;
        //            }
        //            else if (previousDirection == Directions.Down)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = value;
        //            }
        //            if (currentDirection == Directions.Down)
        //                chosenDirectionValue = value;

        //        }
        //        else
        //        {
        //            if (previousDirection == Directions.Up)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = 9;
        //            }
        //            else if (previousDirection == Directions.Down)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = 9;
        //            }
        //            if (currentDirection == Directions.Down)
        //                chosenDirectionValue = 9;

        //            maximum = 9;
        //            chosenDirection = Directions.Down;
        //        }
        //    }
        //    else if (currentDirection != Directions.Up)
        //    {
        //        if (previousDirection == Directions.Up)
        //        {
        //            previousDirectionPreviousValue = previousDirectionValue;
        //            previousDirectionValue = 1;
        //        }
        //        else if (previousDirection == Directions.Down)
        //        {
        //            previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //            previousOppositeDirectionValue = 1;
        //        }
        //    }


        //    // w gore
        //    if (currentDirection != Directions.Down && game.PossibleMoveList.Any(m => m.Action == MoveType.MakeMove && m.MoveDirection == Directions.Up))
        //    {
        //        if ((walls = wallList.Where(w => w.X == myPosition.X && w.Y < myPosition.Y)).Any())
        //        {
        //            if (((value = walls.Min(w => myPosition.Y - w.Y)) <= 8 ? value : (value = 8)) > maximum)
        //            {
        //                maximum = value;
        //                chosenDirection = Directions.Up;
        //            }
        //            else if (value == maximum && currentDirection == Directions.Up)
        //            {
        //                chosenDirection = Directions.Up;
        //            }
        //            if (previousDirection == Directions.Down)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = value;
        //            }
        //            else if (previousDirection == Directions.Up)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = value;
        //            }
        //            if (currentDirection == Directions.Up)
        //                chosenDirectionValue = value;

        //        }
        //        else
        //        {
        //            if (previousDirection == Directions.Down)
        //            {
        //                previousDirectionPreviousValue = previousDirectionValue;
        //                previousDirectionValue = 9;
        //            }
        //            else if (previousDirection == Directions.Up)
        //            {
        //                previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //                previousOppositeDirectionValue = 9;
        //            }
        //            if (currentDirection == Directions.Up)
        //                chosenDirectionValue = 9;
        //            maximum = 9;
        //            chosenDirection = Directions.Up;
        //        }
        //    }
        //    else if (currentDirection != Directions.Down)
        //    {
        //        if (previousDirection == Directions.Down)
        //        {
        //            previousDirectionPreviousValue = previousDirectionValue;
        //            previousDirectionValue = 1;
        //        }
        //        else if (previousDirection == Directions.Up)
        //        {
        //            previousOppositeDirectionPreviousValue = previousOppositeDirectionValue;
        //            previousOppositeDirectionValue = 1;
        //        }
        //    }


        //    if (chosenDirection == Directions.NULL)
        //    {
        //        previousDirection = currentDirection = Directions.NULL;
        //        FindBestMove(state, game);
        //        return;
        //    }
        //    //Console.WriteLine("prevprev " + previousDirectionPreviousValue + " prev " + previousDirectionValue);
        //    // Console.WriteLine("Oppprevprev " + previousOppositeDirectionPreviousValue + " Oppprev " + previousOppositeDirectionValue);
        //    //jesli idziemy w innym kierunku i w poprzednim kierunku korytarz sie nie wydluza, to utrzymaj kierunek
        //    if (game.PossibleMoveList.Any(p => p.Action == MoveType.MakeMove && p.MoveDirection == currentDirection) && previousDirection != Directions.NULL)
        //    {
        //        if (previousDirectionValue <= previousDirectionPreviousValue &&
        //            previousOppositeDirectionPreviousValue >= previousOppositeDirectionValue)
        //        {
        //            // Console.WriteLine("keep current direction");
        //            chosenDirection = currentDirection;
        //        }
        //    }
        //    //Console.WriteLine("Direction " + currentDirection + ", value " + maximum  + ", previousDirection: " + previousDirection);
        //    if (currentDirection != chosenDirection)
        //    {
        //        previousStepsCount = currentStepsCount;
        //        previousDirection = currentDirection;
        //        currentDirection = chosenDirection;
        //    }
        //    else
        //    {
        //        currentStepsCount++;
        //    }
        //    //previousDirection = currentDirection != chosenDirection ? currentDirection : previousDirection;
        //    //currentDirection = chosenDirection;
        //    state.MoveDirection = currentDirection;
        //    state.MoveType = MoveType.MakeMove;
        //    // Console.WriteLine("Direction " + chosenDirection + ", value " + chosenDirectionValue + ", previousDirection: " + previousDirection);
        //}
        #endregion
    }
}